package ch.hearc.infrarouge.database;

import java.util.LinkedList;
import java.util.List;

import ch.hearc.infrarouge.models.Forum;
import ch.hearc.infrarouge.models.ForumThread;
import ch.hearc.infrarouge.models.Reply;
import ch.hearc.infrarouge.models.ThreadMessage;
import ch.hearc.infrarouge.models.User;

public class DBCache {

	private static DBCache instance;

	private List<Forum> forums;
	private List<User> users;
	private List<ForumThread> forumThreads;
	private List<ThreadMessage> threadMessages;
	private List<Reply> replies;

	private DBCache() {
		this.users = new LinkedList<>();
		this.forums = new LinkedList<>();
		this.forumThreads = new LinkedList<>();
		this.threadMessages = new LinkedList<>();
		this.replies = new LinkedList<>();
	}

	public static synchronized DBCache getInstance() {
		if (instance == null) {
			instance = new DBCache();
		}

		return instance;
	}

	private boolean sameNames(String n1, String n2) {
		n1 = n1.toLowerCase();
		n2 = n2.toLowerCase();
		
		int l1 = n1.length();
		int l2 = n2.length();
		
		int minLength = 4;
		
		return (n1.contains(n2) || n2.contains(n1)) && Math.abs(l1 - l2) < Math.min(l1, l2)
				|| n1.startsWith(n2) && l1 >= minLength || n2.startsWith(n1) && l2 >= minLength;
	}

	/**
	 * Finds the user who has the given name. If it doesn't exist, then a new
	 * user is returned.
	 * 
	 * @param name
	 * @return
	 */
	public User findUser(String name, long id) {
		User user = null;

		for (User u : this.users) {
			if (u.getId() == id || sameNames(u.getName(), name)) {
				user = u;
//				if (!name.equals(u.getName()) && name.toLowerCase().contains("labuse") || user.getName().toLowerCase().contains("labuse")) {
//					System.out.println("FOUND user: " + name + "(" + id
//							+ ") = " + user);
//				}
			}
		}

		if (user == null) {
			user = new User(name, users.size());
			this.users.add(user);
		}

		return user;
	}

	@Override
	public String toString() {
		StringBuilder info = new StringBuilder();
		info.append(forums.size() + " forums\n");
		info.append(users.size() + " users\n");
		info.append(forumThreads.size() + " forum threads\n");
		info.append(threadMessages.size() + " thread messages\n");
		info.append(replies.size() + " replies\n");

		return info.toString();
	}

	public List<User> getUsers() {
		return users;
	}

	public void setUsers(List<User> users) {
		this.users = users;
	}

	public List<Forum> getForums() {
		return forums;
	}

	public void setForums(List<Forum> forums) {
		this.forums = forums;
	}

	public List<ForumThread> getForumThreads() {
		return forumThreads;
	}

	public void setForumThreads(List<ForumThread> forumThreads) {
		this.forumThreads = forumThreads;
	}

	public List<ThreadMessage> getThreadMessages() {
		return threadMessages;
	}

	public void setThreadMessages(List<ThreadMessage> threadMessages) {
		this.threadMessages = threadMessages;
	}

	public List<Reply> getReplies() {
		return replies;
	}

	public void setReplies(List<Reply> replies) {
		this.replies = replies;
	}

}
